-- 构造 commonlib 对象
_G.commonlib = _G.commonlib or {};
local commonlib = _G.commonlib;
local __application__ = _G.__application__;

-- 获取全局函数
local _G_load = _G.load;
local _G_xpcall = _G.xpcall;

-- 导入C++函数
local __application__GetFullPath = __application__.GetFullPath;
local __application__GetFileText = __application__.GetFileText;

-- 执行模块
function commonlib.dofile(filename, directory, env, reload)
    if (not filename or filename == "") then return nil end
    
    local __function__, __error__, __module__ = commonlib.loadfile(filename, nil, env, directory, reload);
    local function get_returns(ok, ...)
        if (ok) then
            return ...;
        else
            print(...)
        end
    end
    if (not __function__) then
        commonlib.debugstack(2, __error__);
    else
        print("dofile:", __module__.__filename__);
        return get_returns(_G_xpcall(__function__, function (errmsg)
            if (commonlib.debugstack) then
                return commonlib.debugstack(3, errmsg, false);
            else
                return errmsg;
            end
        end));
    end
end

-- 加载文件
function commonlib.loadfile(filename, mode, env, directory, reload)
    if (not directory or directory == "") then directory = commonlib.GetCurrentDirectory(); end
    local fullpath = __application__GetFullPath(filename or "", directory or "");

    -- 获取模块
    commonlib.__modules__ = commonlib.__modules__ or {};
    commonlib.__modules__[fullpath] = commonlib.__modules__[fullpath] or {};
    local __module__ = commonlib.__modules__[fullpath];

    -- 模块已加载且不需要重新加载 直接返回
    if (__module__.__loaded__ and not reload) then return __module__.__function__, __module__.__error__, __module__ end

    -- 构造模块
    __module__.__filename__ = fullpath;
    __module__.__directory__ = string.gsub(fullpath, "([^\\/]*)$", "");
    __module__.__loaded__ = true;
    __module__.__module__ = {};
    __module__.loadfile = function(_filename, _mode, _env) return commonlib.loadfile(_filename, _mode, _env, __module__.__directory__) end
    __module__.dofile = function(_filename, _env, _reload) return commonlib.dofile(_filename, __module__.__directory__, _env, _reload) end
    
    --  设置元表
    setmetatable(__module__, {__index = type(env) == "table" and env or _G});

    -- 加载文件
    local filetext = __application__GetFileText(fullpath);
    
    -- 编译文件
    if (filetext == "") then
        __module__.__function__, __module__.__error__ = nil, "[ERROR]" .. fullpath .. " is empty file!!!";
    else
        __module__.__function__, __module__.__error__ = _G_load(filetext, fullpath, mode, __module__); 
    end

    return __module__.__function__, __module__.__error__, __module__;
end

-- 获取当前文件路径
function commonlib.GetCurrentFilePath(depth)
    local info = debug.getinfo(depth or 4, "S");
    if (type(info) ~= "table") then return "" end
    local filepath = info.source;
    if (string.sub(filepath, 1, 1) == "@") then filepath = string.sub(filepath, 2); end
    return filepath;
end

-- 获取当前文件目录
function commonlib.GetCurrentDirectory(depth)
    local filepath = commonlib.GetCurrentFilePath(depth or 5);
    local directory = string.gsub(filepath or "", "([^\\/]*)$", "");
    return directory;
end

-- 调试
function commonlib.debugger(ip, port)
    local LuaPanda = _G.dofile("C:/Users/xiaoyao/.vscode/extensions/yinfei.luahelper-0.2.26/debugger/LuaPanda.lua");
    LuaPanda.start(ip or "127.0.0.1", port or 8818);
end

-- 加载模块
commonlib.dofile("commonlib/init.lua")
